#ifndef HASH_H_
#define HASH_H_
typedef struct nlist * nlistlink;
struct nlist {
	nlistlink next;
	char *name;
	char *defn;
};
#define HASHSIZE 101
nlistlink hashtab[HASHSIZE];
unsigned int hash(char *s) {
	int val = 0;
	while (*s) {
		val = *s++ + 31 * val;
	}
	return val % HASHSIZE;
}
nlistlink lookup(char *s) {
	nlistlink ptr = hashtab[hash(s)];
	for (; ptr!=NULL; ptr = ptr->next) {
		if (strcmp(s, ptr->name) == 0)
			break;
	}
	return ptr;
}
nlistlink install(char *name, char *defn) {
	nlistlink head;
	nlistlink np = lookup(name);
	char * cp;
	if (np == NULL) {
		np = (nlistlink) malloc(sizeof(struct nlist));

		cp = malloc(strlen(defn) + 1);
		strcpy(cp, defn);
		np->defn = cp;

		if (np == NULL || cp == NULL)
			return NULL;

		cp = malloc(strlen(name) + 1);
		strcpy(cp, name);
		np->name = cp;

		np->next = hashtab[hash(name)];
		hashtab[hash(name)] = np;
	} else
		free(np->defn);
	cp = malloc(strlen(defn) + 1);
	strcpy(cp, defn);
	np->defn = cp;
	if (cp == NULL)
		return NULL;
	return np;
}
#endif
